昨天我們初步認識了 OOP 三大特性。今天進一步,看看繼承的應用,並帶入 介面 (Interface) 與 DI/IoC 的設計思維。
繼承的好處是 重用程式碼,不用每次都重寫相同的屬性或方法。
/// <summary>
/// 股票基本資訊
/// </summary>
public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}
/// <summary>
/// 股票檔案:繼承 Stock 並擴充產業別
/// </summary>
public class StockProfile : Stock
{
    public string Industry { get; set; }
}
👉 StockProfile 自動擁有 Symbol 和 Price,額外加上 Industry。
介面 是一種「契約」,定義規則,誰實作誰遵守。
/// <summary>
/// 選股策略介面
/// </summary>
public interface IStockStrategy
{
    bool Match(Stock stock);
}
👉 不管策略內容是 MACD、KD 或基本面分析,都必須提供一個 Match 方法。
我們來定義兩個策略:
/// <summary>
/// MACD OSC > 0 則符合
/// </summary>
public class MacdOscStrategy : IStockStrategy
{
    public bool Match(Stock stock)
    {
        // 假設這裡從技術分析模組取出 OSC 值
        decimal osc = GetMacdOsc(stock.Symbol);
        return osc > 0;
    }
    private decimal GetMacdOsc(string symbol)
    {
        // 簡化:真實情況要用技術指標計算
        return 1.23m;
    }
}
/// <summary>
/// KD 黃金交叉 (K 值突破 D 值) 則符合
/// </summary>
public class KdGoldenCrossStrategy : IStockStrategy
{
    public bool Match(Stock stock)
    {
        (decimal k, decimal d) = GetKdValues(stock.Symbol);
        return k > d; // K 線往上突破 D 線
    }
    private (decimal k, decimal d) GetKdValues(string symbol)
    {
        // 簡化:真實情況要透過歷史資料計算
        return (75m, 70m);
    }
}
使用:
Stock s1 = new Stock { Symbol = "2330", Price = 1265m };
IStockStrategy macd = new MacdOscStrategy();
IStockStrategy kd = new KdGoldenCrossStrategy();
Console.WriteLine(macd.Match(s1)); // true
Console.WriteLine(kd.Match(s1));   // true
👉 好處:策略互相獨立,但都能共用同一個介面。
假設我們的 StockService 要用到一個「選股策略」。
傳統的寫法是:
new)。public class StockService
{
    private readonly IStockStrategy _strategy = new MacdOscStrategy(); // 直接 new
    public bool IsMatch(Stock stock)
    {
        return _strategy.Match(stock);
    }
}
👉 問題:
StockService 被「綁死」在 MacdOscStrategy。StockService 的程式碼。public class StockService
{
    private readonly IStockStrategy _strategy;
    public StockService(IStockStrategy strategy) // 由外部注入
    {
        _strategy = strategy;
    }
    public bool IsMatch(Stock stock)
    {
        return _strategy.Match(stock);
    }
}
👉 好處:
MockStrategy。這就是 DI (依賴注入):
把物件的「依賴」交給外部注入,而不是自己 new。
IoC 的概念是:
把控制權交給外部(例如 DI 容器或框架),由它來決定注入哪個物件。
👉 簡單來說:
IoC 是「控制權反轉」的設計理念。
DI 是 IoC 的其中一種具體做法。
如果我們直接在程式裡 new 策略,會發生:
public class StockService
{
    private readonly IStockStrategy _strategy = new MacdOscStrategy(); // 綁死
}
👉 問題:
public class StockService
{
    private readonly IStockStrategy _strategy;
    public StockService(IStockStrategy strategy) // 注入策略
    {
        _strategy = strategy;
    }
    public bool IsMatch(Stock stock)
    {
        return _strategy.Match(stock);
    }
}
使用:
Stock s1 = new Stock { Symbol = "2330", Price = 1265m };
// 換策略只要換注入的物件
StockService service1 = new StockService(new MacdOscStrategy());
StockService service2 = new StockService(new KdGoldenCrossStrategy());
Console.WriteLine(service1.IsMatch(s1)); // true
Console.WriteLine(service2.IsMatch(s1)); // true
👉 好處:
MockStrategy)。今天我們學會了:
StockProfile 基礎上擴充產業別。MacdOscStrategy 與 KdGoldenCrossStrategy。